﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.SqlClient;
using System.Threading;
using System.ComponentModel;
using System.Windows.Controls.Primitives;

namespace PendingTransactions
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private SalesManagerEntities _context = new SalesManagerEntities();
        private int _ownerID;

        public MainWindow()
        {
            InitializeComponent();

            _context.ContextOptions.LazyLoadingEnabled = true;
            _context.CommandTimeout = 600;

            if (App.Args.Count() == 0)
            {
                MessageBox.Show("No OwnerID specified");
                Close();
                return;
            }
            if (!int.TryParse(App.Args[0], out _ownerID))
            {
                MessageBox.Show("Invalid OwnerID specified");
                Close();
                return;
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            LoadGrid();
        }

        private void btnProcess_Click(object sender, RoutedEventArgs e)
        {
            Exception exception = null;

            tblTransaction[] transactions = (tblTransaction[])((CollectionViewSource)FindResource("Transactions")).Source;
            // Clear the PropertyChanged event until after processing.
            foreach (tblTransaction t in transactions)
                t.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(t_PropertyChanged);

            Cursor saveCursor = Cursor;
            Cursor = Cursors.Wait;
            busyIndicator1.IsBusy = true;

            BackgroundWorker th = new BackgroundWorker();
            th.DoWork += (o, eq) =>
            {
                try
                {
                    foreach (tblTransaction t in (from c in transactions where c.Selected && c.TransactionStatusCode == "E" select c))
                    {
                        OnlinePayments.PaymentProcessor.ProcessTransaction((SqlConnection)((System.Data.EntityClient.EntityConnection)_context.Connection).StoreConnection,
                            t.TransactionID);
                        _context.Refresh(System.Data.Objects.RefreshMode.StoreWins, t);
                    }
                }
                catch (Exception err)
                {
                    exception = err;
                }
            };
            th.RunWorkerCompleted += (o, ea) =>
            {
                busyIndicator1.IsBusy = false;
                Cursor = saveCursor;

                if (exception != null)
                {
                    string messages = string.Empty;
                    while (exception != null)
                    {
                        messages += exception.Message + "\n" + exception.StackTrace + "\n";
                        exception = exception.InnerException;
                    }
                    MessageBox.Show("Error processing transactions.\n" + messages);
                }
                else
                {
                    tblTransaction[] posted = transactions.Where(c => c.Selected && c.TransactionStatusCode == "P").ToArray();
                    tblTransaction[] failed = transactions.Where(c => c.Selected && c.TransactionStatusCode == "F").ToArray();
                    MessageBox.Show("Complete!  " + posted.Count().ToString() + " posted in the amount of " + posted.Sum(c => c.Amount).ToString("C") + "\n" +
                        " and " + failed.Count().ToString() + " failed in the amount of " + failed.Sum(c => c.Amount).ToString("C"));
                }
                LoadGrid();
            };
            th.RunWorkerAsync();
        }

        private void btnCreate_Click(object sender, RoutedEventArgs e)
        {
            Cursor saveCursor = Cursor;
            Cursor = Cursors.Wait;
            busyIndicator1.IsBusy = true;

            BackgroundWorker t = new BackgroundWorker();
            DateTime dt = (DateTime)dtAsOf.SelectedDate;
            t.DoWork += (o, eq) =>
                {
                    _context.spCreateTransactions(_ownerID, dt);
                };
            t.RunWorkerCompleted += (o, ea) =>
                {
                    LoadGrid();

                    busyIndicator1.IsBusy = false;
                    Cursor = saveCursor;
                };
            t.RunWorkerAsync();
        }

        private void CalcTotals()
        {
            tblTransaction[] transactions = (tblTransaction[])((CollectionViewSource)FindResource("Transactions")).Source;

            decimal total = 0;
            foreach (tblTransaction t in transactions.Where(c=>c.Selected))
                total += t.Amount;
            lblTotal.Content = total.ToString("C");
        }

        private void LoadGrid()
        {
            tblOwner owner = (tblOwner)_context.GetObjectByKey(new System.Data.EntityKey("SalesManagerEntities.tblOwner", "OwnerID", _ownerID));
            int delay = owner.RetryCardDelay ?? 0;

            DateTime dtDelay = DateTime.Today.AddDays(0 - delay);
            tblTransaction[] transactions =
                (from c in _context.tblTransaction.Include("OrderHeader")
                    .Include("Account")
                    .Include("OrderHeader.Customer")
                    .Include("OrderHeader.Customer.Person")
                    .Include("OrderHeader.CUstomer.Person.Address")
                    .Include("codePaymentProcessor")
                 where c.TransactionStatusCode == "E"
                    && c.Account.OwnerID == _ownerID
                 select c).Union(from c in _context.tblTransaction.Include("OrderHeader")
                    .Include("Account")
                    .Include("OrderHeader.Customer")
                    .Include("OrderHeader.Customer.Person")
                    .Include("OrderHeader.CUstomer.Person.Address")
                    .Include("codePaymentProcessor")
                 where c.TransactionStatusCode == "A"
                    && c.Account.OwnerID == _ownerID
                 select c).ToArray();

            transactions = transactions.Where(c=>!c.TransactionSubmits.Any(ts=>ts.CreateDate >= dtDelay)).ToArray();

            foreach (tblTransaction t in transactions)
            {
                t.Selected = true;
                t.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(t_PropertyChanged);
            }

            ((CollectionViewSource)FindResource("Transactions")).Source = transactions;
            CalcTotals();
        }

        void t_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            CalcTotals();
        }

        private void btnToggle_Click(object sender, RoutedEventArgs e)
        {
            tblTransaction[] transactions = (tblTransaction[])((CollectionViewSource)FindResource("Transactions")).Source;
            foreach (tblTransaction t in transactions)
                t.Selected = !t.Selected;
        }

        private void btnContinuity_Click(object sender, RoutedEventArgs e)
        {
            Cursor saveCursor = Cursor;
            Cursor = Cursors.Wait;
            busyIndicator1.IsBusy = true;

            BackgroundWorker t = new BackgroundWorker();
            DateTime dt = (DateTime)dtAsOf.SelectedDate;
            t.DoWork += (o, eq) =>
            {
                _context.spCreateOrdersForSequences(_ownerID, dt);
            };
            t.RunWorkerCompleted += (o, ea) =>
            {
                LoadGrid();

                busyIndicator1.IsBusy = false;
                Cursor = saveCursor;
            };
            t.RunWorkerAsync();
        }

        private void dtAsOf_Loaded(object sender, RoutedEventArgs e)
        {
            ((DatePicker)sender).SelectedDate = DateTime.Today;
        }
    }
}
